#ifndef BITOPERATION_H
#define BITOPERATION_H
#include <cstdlib>
#include <cstdio>
#include <memory>

#define	GET_LOW_BYTE0(x)	(((x) >>  0) & 0x000000ff)	  /* 获取第0个字节 */
#define	GET_LOW_BYTE1(x)	(((x) >>  8) & 0x000000ff)	  /* 获取第1个字节 */
#define	GET_LOW_BYTE2(x)	(((x) >> 16) & 0x000000ff)	  /* 获取第2个字节 */
#define	GET_LOW_BYTE3(x)	(((x) >> 24) & 0x000000ff)	  /* 获取第3个字节 */
#define GET_LOW_BYTE(x,n)   (((x)>>((n)*8)) & 0x000000ff) /* 获取第n个字节 */

#define	CLEAR_LOW_BYTE0(x)	(x &= 0xffffff00)	/* 清零第0个字节 */
#define	CLEAR_LOW_BYTE1(x)	(x &= 0xffff00ff)	/* 清零第1个字节 */
#define	CLEAR_LOW_BYTE2(x)	(x &= 0xff00ffff)	/* 清零第2个字节 */
#define	CLEAR_LOW_BYTE3(x)	(x &= 0x00ffffff)	/* 清零第3个字节 */
#define	CLEAR_LOW_BYTE(x,n)	(x &= (~(0xff<<((n)*8))))	/* 清零第n个字节 */

#define	SET_LOW_BYTE0(x)  (x |= 0x000000ff)	/* 第0个字节置1 */
#define	SET_LOW_BYTE1(x)  (x |= 0x0000ff00)	/* 第1个字节置1 */
#define	SET_LOW_BYTE2(x)  (x |= 0x00ff0000)	/* 第2个字节置1 */
#define	SET_LOW_BYTE3(x)  (x |= 0xff000000)	/* 第3个字节置1 */
#define	SET_LOW_BYTE(x,n) (x |= (0xff<<((n)*8)))	/* 第3个字节置1 */

#define	clr_bit(x, bit)	((x) &= ~(1 << (bit)))	        /* 清零第bit位 */
#define	set_bit(x, bit)	((x) |= (1 << (bit)))	        /* 置位第bit位 */
#define	get_bit(x, bit)	(((x) & (1 << (bit))) >> (bit))	/* 获取第bit位 */
#define SET_BIT(a,n1,b,n2)(get_bit(b,n2)?set_bit(a,n1):clr_bit(a,n1))/**/
#define BIT_M_TO_N(x, m, n)  ((unsigned int)((x) << (31-(n))) >> ((31 - (n)) + (m)))/*取m到n的连续几位的值*/
inline void setBit(int a,int n1,int b,int n2){get_bit(b,n2)?set_bit(a,n1):clr_bit(a,n1);}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
//二进制打印输出
inline void BitPrint(unsigned char n)
{
    int i;
    for (i=7;i>=0;i--)
    {
        printf("%u",(n>>i)&1);
    }
}
//按比特位拷贝
// 从src数组首地址跳过sbb个字节，又跳过ssb个比特位，拷贝nbits个比特位的数据到
//   dest数组首地址跳过dbb个字节，又跳过dsb个比特位位置
int copybits(const unsigned char* src,int sbb/*source begin byte*/,
             int ssb/*source skip bit*/,
             unsigned char* dest,
             int dbb/*dest begin byte*/,
             int dsb/*dest skip bit*/,
             int nbits);
typedef unsigned char uchar;
typedef unsigned char BYTE;
typedef unsigned long DWORD;
typedef unsigned int  UINT32;
class BitStream{
public:
    BitStream(std::shared_ptr<BYTE> buffer, UINT32 capacity);
    ~BitStream();
    void bitStreamPrefetch();//预取
    void bitStreamFetch();   //获得
    void bitStreamFlush();   //刷新
    void bitStreamShift(int n);//左移
    void bitStreamWriteBits(int bits, int nbits);//写数据
private:
    std::shared_ptr<BYTE> buffer;  //缓冲区
    std::shared_ptr<BYTE> pointer; //指针
    DWORD position=0;//位置
    DWORD length;  //长度
    DWORD capacity;//容量
    UINT32 mask;   //面具
    UINT32 offset=0; //抵消
    UINT32 prefetch;//预取
    UINT32 accumulator=0;//蓄电池
};

struct _wBitStream
{
    BYTE* buffer;  //缓冲区
    BYTE* pointer; //指针
    DWORD position;//位置
    DWORD length;  //长度
    DWORD capacity;//容量
    UINT32 mask;   //面具
    UINT32 offset; //抵消
    UINT32 prefetch;//预取
    UINT32 accumulator;//蓄电池
};
typedef struct _wBitStream wBitStream;

//预取
#define BitStream_Prefetch(_bs) do { \
(_bs->prefetch) = 0; \
    if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 4)) \
    (_bs->prefetch) |= (*(_bs->pointer + 4) << 24); \
    if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 5)) \
    (_bs->prefetch) |= (*(_bs->pointer + 5) << 16); \
    if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 6)) \
    (_bs->prefetch) |= (*(_bs->pointer + 6) << 8); \
    if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 7)) \
    (_bs->prefetch) |= (*(_bs->pointer + 7) << 0); \
} while(0)
//获得
#define BitStream_Fetch(_bs) do { \
    (_bs->accumulator) = 0; \
    if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 0)) \
    (_bs->accumulator) |= (*(_bs->pointer + 0) << 24); \
    if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 1)) \
    (_bs->accumulator) |= (*(_bs->pointer + 1) << 16); \
    if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 2)) \
    (_bs->accumulator) |= (*(_bs->pointer + 2) << 8); \
    if (((UINT32) (_bs->pointer - _bs->buffer)) <(_bs->capacity + 3)) \
    (_bs->accumulator) |= (*(_bs->pointer + 3) << 0); \
    BitStream_Prefetch(_bs); \
} while(0)
//刷新
#define BitStream_Flush(_bs) do { \
    if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 0)) \
            *(_bs->pointer + 0) = (_bs->accumulator >> 24); \
    if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 1)) \
        *(_bs->pointer + 1) = (_bs->accumulator >> 16); \
    if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 2)) \
        *(_bs->pointer + 2) = (_bs->accumulator >> 8); \
    if (((UINT32) (_bs->pointer - _bs->buffer)) < (_bs->capacity + 3)) \
        *(_bs->pointer + 3) = (_bs->accumulator >> 0); \
} while(0)
//左移
#define BitStream_Shift(_bs, _nbits) do { \
    _bs->accumulator <<= _nbits; \
    _bs->position += _nbits; \
    _bs->offset += _nbits; \
    if (_bs->offset < 32) { \
        _bs->mask = ((1 << _nbits) - 1); \
        _bs->accumulator |= ((_bs->prefetch >> (32 - _nbits)) & _bs->mask); \
        _bs->prefetch <<= _nbits; \
    } else { \
        _bs->mask = ((1 << _nbits) - 1); \
        _bs->accumulator |= ((_bs->prefetch >> (32 - _nbits)) & _bs->mask); \
        _bs->prefetch <<= _nbits; \
        _bs->offset -= 32; \
        _bs->pointer += 4; \
        BitStream_Prefetch(_bs); \
        if (_bs->offset) { \
            _bs->mask = ((1 << _bs->offset) - 1); \
            _bs->accumulator |= ((_bs->prefetch >> (32 - _bs->offset)) & _bs->mask); \
            _bs->prefetch <<= _bs->offset; \
        } \
    } \
} while(0)
//写数据
#define BitStream_Write_Bits(_bs, _bits, _nbits) do { \
    _bs->position += _nbits; \
    _bs->offset += _nbits; \
    if (_bs->offset < 32) { \
        _bs->accumulator |= (_bits << (32 - _bs->offset)); \
    } else { \
        _bs->offset -= 32; \
        _bs->mask = ((1 << (_nbits - _bs->offset)) - 1); \
        _bs->accumulator |= ((_bits >> _bs->offset) & _bs->mask); \
        BitStream_Flush(bs); \
        _bs->accumulator = 0; \
        _bs->pointer += 4; \
        if (_bs->offset) { \
            _bs->mask = ((1 << _bs->offset) - 1); \
            _bs->accumulator |= ((_bits & _bs->mask) << (32 - _bs->offset)); \
        } \
    } \
} while(0)

void BitStream_Attach(wBitStream* bs, BYTE* buffer, UINT32 capacity);

wBitStream* BitStream_New();
void BitStream_Free(wBitStream* bs);

inline void printNum(int num,unsigned int rix){
    char s[32];
    if(_itoa(num,s,rix)){
        printf(s);
    }
}

#include <QByteArray>
inline QByteArray UCharXOR(const QByteArray& a,const QByteArray& b){
    const QByteArray* bytes1,*bytes2;
    int len1,len2;
    if(a.size()>b.size()){
        bytes1=&a;
        bytes2=&b;
        len1=a.size();
        len2=b.size();
    }else{
        bytes1=&b;
        bytes2=&a;
        len1=b.size();
        len2=a.size();
    }
    QByteArray ans{len1,'\0'};
    int i=0;
    for(;i<len2;++i){
        ans[i]=(*bytes1)[i]^(*bytes2)[i];
    }
    for(;i<len1;++i){
        ans[i]=(*bytes1)[i];
    }
    return ans;
}
#endif // BITOPERATION_H
